"""
Copyright 2012 Wieser Dietmar, Margit Mutschlechner.

This file is part of Multimedia Social Networking Platform.

Multimedia Social Networking Platform is free software: 
you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Multimedia Social Networking Platform is distributed
in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Multimedia Social Networking Platform.  
If not, see <http://www.gnu.org/licenses/>.

"""

from PyQt4 import QtGui, QtCore
from msnp.gui import UIText, Resources, GUIHelper, MyStyle
from msnp.service.network.model.CustodyModel import CustodyQueueType
from msnp.model import PTPModel
from msnp.service.network import NetworkController
from msnp.service.network.model import CustodyModel
from msnp import gui

class MessageWidget(QtGui.QDialog):
    """This class contains a message dialog to display messages sent by the application to inform the user about important news,
    eg. change of membership status.
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing all items of the widget, either a MessageSplashWidget or the items __tabWidget and __butDiscard.
        __tabWidget: A QTabWidget object containing all items of the list __tabs. It is connected to the method __closeTab() when closing.
        __tabs: A list of TabMemberStatusChanged objects.
        __firstTabClose: A boolean value, True if there was already a tab closed, False otherwise.
        __butDiscard: A QPushButton object connected to the method close().
    """
    
    def __init__(self, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__tabs = None
        self.__tabWidget = None
        self.setWindowIcon(QtGui.QIcon(Resources.IMAGE_MESSAGE))
        self.setFixedSize(400, 400)
        self.__mainLayout = QtGui.QVBoxLayout()
#        self.setModal(True)
        self.setLayout(self.__mainLayout)
        GUIHelper.centerWidget(self)
        
    def buildMessageSplashWidget(self):
        """Initializes the item __mainLayout with a MessageSplashWidget."""
        self.setWindowTitle(UIText.TITLE_PLEASE_WAIT)
        self.__cleanLayout()
        messageSplashWidget = MessageSplashWidget()
        self.__mainLayout.addWidget(messageSplashWidget)
        self.setFixedSize(500, 450)
        self.repaint()

    def buildMessageWidget(self):
        """Initializes the item __mainLayout with the items __tabWidget and __butDiscard."""
        self.setWindowTitle(UIText.TITLE_MESSAGES)
        self.__cleanLayout()
        self.__initTabs()
        self.__initButtons()
        self.__mainLayout.addWidget(self.__tabWidget)
        self.__mainLayout.addWidget(self.__butDiscard)
    
    def __cleanLayout(self):
        """Removes everything from the item __mainLayout."""
        import sip
        if self.layout() != None:
            oldLayout = self.layout()
            for i in reversed(range(oldLayout.count())):
                oldLayout.itemAt(i).widget().setParent(None)
            sip.delete(oldLayout)
        self.__mainLayout = QtGui.QVBoxLayout()
        self.setLayout(self.__mainLayout)
        self.__tabs = None
        self.__tabWidget = None
        
    def __initTabs(self):
        """Initializes the QTabWidget object __tabWidget."""
        self.__firstTabClose = True
        self.__tabWidget = QtGui.QTabWidget(self)
        self.__tabWidget.setTabsClosable(True)
        self.__tabWidget.connect(self.__tabWidget, QtCore.SIGNAL('tabCloseRequested (int)'), self.__closeTab)
        self.__tabs = []
        
    def __initButtons(self):
        """Initializes the QPushButton object __butDiscard."""
        self.__butDiscard = QtGui.QPushButton(UIText.BUT_DISCARD_ALL_MSG, self)
        self.__butDiscard.setFocusPolicy(QtCore.Qt.NoFocus)
        self.__butDiscard.setIcon(QtGui.QIcon(Resources.IMAGE_BUT_DISCARD))
        self.connect(self.__butDiscard, QtCore.SIGNAL('clicked()'), self.close)
            
    def newMessages(self, newMessages):
        """This message is called if a new message arrives. The item __tabWidget is initialized, if not done before,
        and a new TabMemberStatusChanged object is created for the given new message."""
        if self.__tabWidget == None:
            self.buildMessageWidget()
        for newMsg in newMessages:
            self.__createTab(newMsg)

    def __createTab(self, msg):
        """Creates a new TabMemberStatusChanged item for the given message and adds it to the item __tabWidget and __tabs."""
        if msg.getQueueType() == CustodyQueueType.MEMBER_STATUS_CHANGED:
            self.__checkConfirmBtns(msg.getGroupname(), msg.getOwnername(), msg.getMembername())
            tab = TabMemberStatusChanged(msg, self)
            self.__tabWidget.addTab(tab, UIText.LABEL_STATUS_CHANGE)
        self.__tabs.append(tab)

    def __checkConfirmBtns(self, groupname, ownername, membername):
        """Checks whether the QPushButton __butConfirm of the corresponding item TabMemberStatusChanged should be enabled or not."""
        for tab in self.__tabs:
            if isinstance(tab, TabMemberStatusChanged):
                if tab.getStatus() == PTPModel.MemberStatus.NOT_CONFIRMED and tab.isBtnConfirmEnabled():
                    if tab.getGroupname() == groupname and tab.getOwnername() == ownername and tab.getMembername() == membername:
                        tab.disableBtnConfirm()
                        break
    
    def __closeTab(self):
        """This method is called when an item of the item __tabWidget is closing.
        It asks the user if it really wants to close the tab and eventually closes it."""
        discard = QtGui.QMessageBox.Yes
        if self.__firstTabClose:
            discard = QtGui.QMessageBox.question(self, UIText.MSG_ATTENTION, UIText.MSG_REALLY_DISCARD_MESSAGE, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
            self.__firstTabClose = False
        if discard == QtGui.QMessageBox.Yes:
            index = self.__tabWidget.currentIndex()
            self.__tabWidget.removeTab(index)
            self.__tabs.__delitem__(index)
                                        
    def closeEvent(self, event):
        """This method is called when the widget is closed.
        It asks the user if it really wants to close the widget and eventually closes it."""
        if self.__tabs != None and len(self.__tabs) > 0:
            discard = QtGui.QMessageBox.question(self, UIText.MSG_ATTENTION, UIText.MSG_REALLY_DISCARD_MESSAGE, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
            if discard == QtGui.QMessageBox.Yes:
                gui.GUIController.closeMessageWidget()
                event.accept()
            else:
                event.ignore()


class MessageSplashWidget(QtGui.QWidget):
    """This class contains a message splash widget displayed while waiting for the retrieval of the messages to be displayed.
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing the items __lblSplash and __lblLoading.
        __lblSplash: A QLabel object.
        __lblLoading: A QLabel object containing the item __movie.
        __movie: A QMovie object.
    """
    def __init__(self, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__mainLayout = QtGui.QVBoxLayout()
        self.__build()
        self.setLayout(self.__mainLayout)
        
    def __build(self): 
        """Initializes the widget."""
        self.__initSplashLabels()
        self.__mainLayout.addWidget(self.__lblSplash)
        self.__mainLayout.addWidget(self.__lblLoading)
        
    def __initSplashLabels(self):
        """Initializes the QLabel objects __lblSplash and __lblLoading and the QMovie object __movie."""
        #movie container
        self.__lblSplash = QtGui.QLabel()
#        self.__lblSplash.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        self.__lblSplash.setAlignment(QtCore.Qt.AlignCenter)
        #create movie
        self.__movie = QtGui.QMovie(Resources.IMAGE_LOADING, QtCore.QByteArray(), self)
        self.__movie.setCacheMode(QtGui.QMovie.CacheAll)
        self.__movie.setSpeed(100)
        self.__lblSplash.setMovie(self.__movie)
        self.__movie.start()
        self.__lblLoading = QtGui.QLabel(UIText.LABEL_LOADING_MESSAGES)
        self.__lblLoading.setAlignment(QtCore.Qt.AlignHCenter)
            
        
class TabMemberStatusChanged(QtGui.QWidget):
    """This class contains a tab where member status changed messages are displayed.
    
    Parameters:
        __parent: A QWidget object containing the parent frame. Default None.
        __mainLayout: A QVBoxLayout object containing the items __txtSummary, __msgDetailsWidget and, if needed, the item __butConfirm.
        __message: A MemberStatusChangedMessage object containing the message to display.
        __txtSummary: A QLineEdit object.
        __msgDetailsWidget: A QWidget object containing the items __lblTimeBold, __lblTime, __lblMemberBold, __lblMember, __lblGroupBold, __lblGroup, __lblOwnerBold, __lblOwner, __lblResultBold and __lblResult. 
        __lblTimeBold: A QLabel object.
        __lblTime: A QLabel object.
        __lblMemberBold: A QLabel object.
        __lblMember: A QLabel object.
        __lblGroupBold: A QLabel object.
        __lblGroup: A QLabel object.
        __lblOwnerBold: A QLabel object.
        __lblOwner: A QLabel object.
        __lblResultBold: A QLabel object.
        __lblResult: A QLabel object.
        __butConfirm: A QPushButton object connected to the method __confirmMember().
    """
    def __init__(self, message, parent=None):
        """The init-method."""
        QtGui.QWidget.__init__(self, parent)
        self.__parent = parent
        self.__message = message
        self.__mainLayout = QtGui.QVBoxLayout()
        self.__build()
        self.setLayout(self.__mainLayout)
    
    def __build(self):
        """Initializes the widget and its contained items."""
        self.__initLabels()
        self.__initMsgDetailsWidget()
        self.__mainLayout.addWidget(self.__txtSummary)
        self.__mainLayout.addWidget(self.__msgDetailsWidget)
        if self.getStatus() == PTPModel.MemberStatus.NOT_CONFIRMED and self.getOwnername() == NetworkController.getMySelf().getMyIdentity().getName():
            self.__initButton()
            self.__mainLayout.addWidget(self.__butConfirm)
        
    def __initLabels(self):
        """Initializes the QTextEdit object __txtSummary and the QLabel objects __lblTimeBold, __lblTime, __lblMemberBold, __lblMember,
        __lblGroupBold, __lblGroup, __lblOwnerBold, __lblOwner, __lblResultBold and __lblResult."""
        timestamp = str(self.__message.getTimestamp())
        membername = self.getMembername()
        groupname = self.getGroupname()
        ownername = self.getOwnername()
        result = self.__message.getResult()
        status = self.getStatus()
            
        self.__txtSummary = QtGui.QTextEdit()
        self.__txtSummary.setText(CustodyModel.getReadableMessage(self.__message))
        self.__txtSummary.setEnabled(False)
        
        self.__lblTimeBold = QtGui.QLabel(UIText.LABEL_TIME + ":")
        self.__lblTimeBold.setFont(MyStyle.getFont13Bold())
        self.__lblTime = QtGui.QLabel(timestamp)
        
        self.__lblMemberBold = QtGui.QLabel(UIText.LABEL_MEMBER + ":")
        self.__lblMemberBold.setFont(MyStyle.getFont13Bold())
        self.__lblMember = QtGui.QLabel(membername)
        
        self.__lblGroupBold = QtGui.QLabel(UIText.LABEL_GROUP + ":")
        self.__lblGroupBold.setFont(MyStyle.getFont13Bold())
        self.__lblGroup = QtGui.QLabel(groupname)
        
        self.__lblOwnerBold = QtGui.QLabel(UIText.LABEL_OWNER + ":")
        self.__lblOwnerBold.setFont(MyStyle.getFont13Bold())
        self.__lblOwner = QtGui.QLabel(ownername)
        
        self.__lblResultBold = QtGui.QLabel(UIText.LABEL_RESULT + ":")
        self.__lblResultBold.setFont(MyStyle.getFont13Bold())
        if status == None:
            self.__lblResult = QtGui.QLabel(result)
        else:
            self.__lblResult = QtGui.QLabel(status)
        
    def __initButton(self):
        """Initializes the QPushButton object __butConfirm and connects it to the method __confirmMember()."""
        self.__butConfirm = QtGui.QPushButton(UIText.BUT_CONFIRM_MEMBER, self)
        self.__butConfirm.setFocusPolicy(QtCore.Qt.NoFocus)
        self.__butConfirm.setIcon(QtGui.QIcon(Resources.IMAGE_CONFIRM_MEMBERS))
        self.connect(self.__butConfirm, QtCore.SIGNAL('clicked()'), self.__confirmMember)
    
    def __initMsgDetailsWidget(self):
        """Initializes the item __msgDetailsWidget and adds its contained items."""
        self.__msgDetailsWidget = QtGui.QWidget()
        gridLayout = QtGui.QGridLayout()
        gridLayout.setColumnStretch(1, 1)
        gridLayout.addWidget(self.__lblTimeBold, 0, 0)
        gridLayout.addWidget(self.__lblTime, 0, 1)
        gridLayout.addWidget(self.__lblMemberBold, 1, 0)
        gridLayout.addWidget(self.__lblMember, 1, 1)
        gridLayout.addWidget(self.__lblGroupBold, 2, 0)
        gridLayout.addWidget(self.__lblGroup, 2, 1)
        gridLayout.addWidget(self.__lblOwnerBold, 3, 0)
        gridLayout.addWidget(self.__lblOwner, 3, 1)
        gridLayout.addWidget(self.__lblResultBold, 4, 0)
        gridLayout.addWidget(self.__lblResult, 4, 1)
        self.__msgDetailsWidget.setLayout(gridLayout)
        
    def __confirmMember(self):
        """This method is connected to the QPushButton object __butConfirm."""
        groupname = self.getGroupname()
        ownername = self.getOwnername()
        membername = self.getMembername()
        status = PTPModel.MemberStatus.ACTIVE
        NetworkController.changeMemberStatus(membername, groupname, ownername, status)
        self.disableBtnConfirm()
        
    def getGroupname(self):
        """Returns the field __groupname of the MemberStatusChangedMessage object __message."""
        if self.__message != None:
            return self.__message.getGroupname()
        return None
    
    def getOwnername(self):
        """Returns the field __ownername of the MemberStatusChangedMessage object __message."""
        if self.__message != None:
            return self.__message.getOwnername()
        return None
    
    def getMembername(self):
        """Returns the field __membername of the MemberStatusChangedMessage object __message."""
        if self.__message != None:
            return self.__message.getMembername()
        return None
    
    def getStatus(self):
        """Returns the field __status of the MemberStatusChangedMessage object __message."""
        if self.__message != None:
            return self.__message.getStatus()
        return None
    
    def isBtnConfirmEnabled(self):
        """Checks whether the QPushButton object __butConfirm should be enabled or not."""
        if self.getOwnername() != NetworkController.getMySelf().getMyIdentity().getName():
            return False
        return self.__butConfirm.isEnabled()
    
    def disableBtnConfirm(self):
        """Sets the item __butConfirm to disabled."""
        self.__butConfirm.setEnabled(False)
        
